home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 001-025 / scopedisk3 / 68kasm / src / a68k.doc next >
Text File  |  1995-03-18  |  19KB  |  415 lines

  1.     A68k - a freely    distributable assembler    for the    Amiga
  2.  
  3.             by Charlie Gibbs
  4.  
  5.              with special thanks to
  6.         Brian R. Anderson and Jeff Lydiatt
  7.  
  8.          (Version 1.10 - March 20, 1988)
  9.  
  10.      Note: This    program    is NOT Public Domain.  Permission is given
  11. to freely distribute this program provided no fee is charged, and this
  12. documentation file is included with the    program.
  13.  
  14.      This assembler is based on    Brian R. Anderson's 68000 cross-
  15. assembler published in Dr. Dobb's Journal, April through June 1986.
  16. I have converted it to produce AmigaDOS-format object modules, and
  17. have made many enhancements, such as macros and    include    files.
  18.  
  19.      My    first step was to convert the original Modula-2    code into C.
  20. I did this for two reasons.  First, I had access to a C    compiler, but
  21. not a Modula-2 compiler.  Second, I like C better anyway.
  22.  
  23.      The executable code generator code    (GetObjectCode and MergeModes)
  24. is essentially the same    as in the original article, aside from its
  25. translation into C.  I have almost completely rewritten    the remainder
  26. of the code, however, in order to remove restrictions, add enhancements,
  27. and adapt it to    the AmigaDOS environment.  Since the only reference book
  28. available to me    was the    AmigaDOS Developer's Manual (Bantam, February
  29. 1986), the assembler and the remainder of this document    work in    terms
  30. of that    book.
  31.  
  32.  
  33. RESTRICTIONS
  34.  
  35.      Let's get these out of the way first.  There are a few things that I
  36. have not yet implemented, and some outright bugs that would take too long
  37. to correct for this version.
  38.  
  39.       o    The verification file (-v) option is not supported.  Diagnostic
  40.     messages always    appear on the console.    They also appear in the
  41.     listing    file, however (see extensions below).  You can produce
  42.     an error file by redirecting console output to a file -    the
  43.     line number counter and    final summary are displayed on stderr
  44.     so you can still see what's happening.
  45.  
  46.       o    The file names in the include directory    list (-i) must be separated
  47.     by commas.  The    list may not be    enclosed in quotes.
  48.  
  49.       o    Labels assigned    by EQUR    and REG    directives are case-sensitive.
  50.  
  51.       o    The following directives are not supported, and    will be    flagged    as
  52.     invalid    op-codes:
  53.  
  54.         RORG
  55.         OFFSET
  56.         NOPAGE
  57.         LLEN
  58.         PLEN
  59.         NOOBJ
  60.         FAIL
  61.         FORMAT
  62.         NOFORMAT
  63.         MASK2
  64.  
  65.     I feel that NOPAGE, LLEN, and PLEN should not be defined within    a
  66.     source module.    It doesn't make sense to me to have to change your
  67.     program    just because you want to print your listings on    different
  68.     paper.    The command-line option    "-p" (see below) can be used as a
  69.     replacement for    PLEN.
  70.  
  71.  
  72. EXTENSIONS
  73.  
  74.      Now for the good stuff:
  75.  
  76.       o    Labels can be any length that will fit onto one    source line
  77.     (currently 127 bytes maximum).    Since labels are stored    on the
  78.     heap, the number of labels that    can be processed is limited only
  79.     by available memory, which can be increased by using the "-w"
  80.     option (see below).
  81.  
  82.       o    Since section data and user macro definitions are stored on the
  83.     same heap as the symbol    table (see above), they    too are    limited
  84.     only by    available memory.  (Actually, there is a hard-coded limit
  85.     of 32767 sections, but I doubt anyone will run into that one.)
  86.  
  87.       o    The only values    a label    cannot take are    the register names - the
  88.     assembler can distinguish between the same name    used as    a label,
  89.     instruction name, macro    name, directive, or section name.
  90.  
  91.       o    Section    and user macro names appear in the symbol table    dump, and
  92.     will also be cross-referenced.    Their names can    be the same as any
  93.     label (see above); the assembler can sort them out.
  94.  
  95.       o    Includes and macro calls can be    nested indefinitely, limited only
  96.     by available memory.  The message "Secondary heap overflow -
  97.     assembly terminated" will be displayed if memory is exhausted.
  98.     You can    increase the size of this heap using the -w parameter
  99.     (see below).  Recursive    macros are supported; recursive    includes
  100.     will, of course, result    in a loop that will be broken only when
  101.     the heap overflows.
  102.  
  103.       o    The EVEN directive forces alignment on a word (2-byte) boundary.
  104.     It does    the same thing as CNOP 0,2.
  105.     (This one is left over from the    original code.)
  106.  
  107.       o    Branch (Bcc) instructions to a previously-defined label    will be
  108.     automatically converted    to short form if possible.  This feature is
  109.     not available for forward branches, since in pass 1 the    assembler
  110.     doesn't yet know how far the branch must go.
  111.  
  112.       o    Backward references to labels within the current CODE section
  113.     will be    converted to PC    relative addressing with displacement
  114.     if this    mode is    legal for the instruction.
  115.  
  116.       o    If a MOVEM instruction only specifies one register, it is converted
  117.     to the corresponding MOVE instruction.    Instructions of    the form
  118.     MOVEM D0-D0,label will not be converted, however.
  119.  
  120.       o    ADD, SUB, and MOVE instructions    will be    converted to ADDQ, SUBQ,
  121.     and MOVEQ respectively if possible.  Instructions coded    explicitly
  122.     as (for    example) ADDA or ADDI will not be converted.
  123.  
  124.       o    ADD, CMP, SUB, and MOVE    to an address register are converted to
  125.     ADDA, CMPA, SUBA, and MOVEA respectively, except if an ADD, SUB,
  126.     or MOVE    instruction has    already    been converted to quick    form.
  127.  
  128.       o    ADD, AND, CMP, EOR, OR,    and SUB    of an immediate    value are converted
  129.     to ADDI, ANDI, CMPI, EORI, ORI,    and SUBI respectively (unless the
  130.     address    register or quick conversion above has already been done).
  131.  
  132.       o    If both    operands of a CMP instruction are postincrement    mode, the
  133.     instruction is converted to CMPM.
  134.  
  135.       o    The SECTION directive allows a third parameter.     This can be
  136.     specified as either CHIP or FAST (upper- or lower-case).  If this
  137.     parameter is present, the hunk will be written with the    MEMF_CHIP
  138.     or MEMF_FAST bit set.  This allows you to produce "pre-ATOMized"
  139.     object modules.
  140.  
  141.       o    The synonyms DATA and BSS are accepted for SECTION directives
  142.     starting data or BSS hunks.  The CHIP and FAST options mentioned
  143.     above can also be used,    e.g. BSS name,CHIP.
  144.  
  145.       o    The ability to produce Motorola    S-records is retained from the
  146.     original code.    The -s option causes the assembler to produce
  147.     S-format instead of AmigaDOS format.  Relocatable code cannot be
  148.     produced in this format.
  149.  
  150.       o    Error messages consist of three    parts.
  151.         The    position of the    offending line is given    as a line number
  152.     within the current module.  If the line    is within a macro expan-
  153.     sion or    INCLUDE    file, the position of the macro    call or    INCLUDE
  154.     statement in the outer module is given as well.     This process
  155.     is repeated until the outermost    source module is reached.
  156.         Next, the offending    source line itself is listed.
  157.         Finally, the errors    for that line are displayed.  A    flag
  158.     (^) is placed under the    column where the error was detected.
  159.  
  160.       o    Named local labels are supported.  These work the same as the
  161.     local labels supported by the Metacomco    assembler (nnn$) but
  162.     can be formed in the same manner as normal labels, except that
  163.     they must be preceded by a backslash.
  164.  
  165.       o    The following synonyms have been implemented for compatibility
  166.     with the Aztec assembler:
  167.         CSEG is    treated    the same as CODE or SECTION name,CODE
  168.         DSEG is    treated    the same as DATA or SECTION name,DATA
  169.  
  170.       o    The following synonyms have been implemented for compatibility
  171.     with the Assempro assembler:
  172.         ENDIF is treated the same as ENDC
  173.         = is treated the same as EQU
  174.         | is treated the same as ! (logical OR)
  175.  
  176.       o    Quotation marks    (") can be used as string delimiters
  177.     as well    as apostrophes (').  Any given string must begin
  178.     and end    with the same delimiter.  This allows such statements
  179.     as the following:
  180.         MOVEQ    '"',D0
  181.         DC.B    "This is Charlie's assembler."
  182.     Note that you can still    define an apostrophe within a string
  183.     delimited by apostrophes if you    double it, e.g.
  184.         MOVEQ    """",D0
  185.         DC.B    'This is Charlie''s assembler.'
  186.  
  187.       o    If any errors are found    in the assembly, the object code file
  188.     will be    scratched, unless you specified    the -k (keep) flag
  189.     on the command line.
  190.  
  191.       o    The symbol .A68K (note upper case) is automatically defined
  192.     as a SET symbol    having an absolute value of 1.    This enables
  193.     a source program to determine whether it is being assembled
  194.     on this    assembler.
  195.  
  196.  
  197. HOW TO USE IT
  198.  
  199.      The command-line syntax to    run the    assembler is as    follows:
  200.  
  201.     a68k <source file>
  202.         [-d]
  203.         [-e<equate file>]
  204.         [-h<header file>]
  205.         [-i<include dirlist>]
  206.         [-k]
  207.         [-l<listing file>]
  208.         [-o<object file>]
  209.         [-p<page depth>]
  210.         [-q[<quiet interval>]]
  211.         [-s]
  212.         [-t]
  213.         [-w[<primary-heap-size>][,secondary-heap-size]]
  214.         [-x]
  215.         [-z[<debug-start-line>][,debug-end-line]]
  216.  
  217. These options can be given in any order, so if you like    to specify your
  218. switches first,    you can.  Option values, if any, must immediately follow
  219. the keyword with no intervening    spaces.
  220.  
  221.      If    the -o keyword is omitted, the object file will    be given a default
  222. name.  It is created by    replacing all characters after the last    period in
  223. the source file    name by    "o".  For example, if the source file name is
  224. "myprog.asm", the object file name defaults to "myprog.o".  A source name
  225. of "my.new.prog.asm" produces a default object file name of "my.new.prog.o".
  226. If the source file name    does not contain a period, ".o" is appended to it
  227. to produce the default object file name.
  228.  
  229.      The default value for the listing file name is arrived at in the same
  230. way as the object file name, except that ".lst" is appended instead of ".o".
  231. If you don't specify this parameter, no listing file will be produced.
  232. If you specify -x (see below), -l (with    the default name) is assumed,
  233. although you can still use this    parameter if you wish.
  234.  
  235.      The default value for the equate file name    is arrived at in the same
  236. way as the object file name, except that ".equ" is appended instead of ".o".
  237.  
  238.      The include directory list    is a list of directory names separated by
  239. commas.     No embedded blanks are    allowed.  For example, the specification
  240.     -imylib,df1:another.lib
  241. will cause include files to be searched    for first in the current directory,
  242. then in    "mylib", then in "df1:another.lib".
  243.  
  244.      The -d keyword causes symbol table    entries    (hunk_symbol) to be written
  245. to the object module for the use of symbolic debuggers.
  246.  
  247.      The -k keyword causes the object file to be kept if any errors were
  248. found.    Otherwise, it will be scratched    if any errors occurred.
  249.  
  250.      The -p keyword causes the page depth to be    set to the specified value.
  251. If omitted, a default of 60 lines (-p60) is assumed.
  252.  
  253.      The -q keyword changes the    interval at which A68k displays    the
  254. current    line number (the default is every 10 lines, i.e. -q10).     If
  255. you specify -q0    or -q without a    value, no line numbers will be displayed.
  256. This will speed    up assemblies slightly by reducing console I/O.
  257.  
  258.      The -s keyword, if    specified, causes the object file to be    written    in
  259. Motorola S-record format.  If omitted, AmigaDOS    format will be produced.
  260. The default name for an    S-record file has ".s" appended to the source name,
  261. rather than ".o"; this can still be overridden with the -o keyword, though.
  262.  
  263.      The -t keyword allows tabs    in the source file to be passed    through
  264. to the listing file, rather than being expanded.  In addition, tabs will
  265. be generated in    the listing file to skip from the object code to the
  266. source statement, etc.    This can greatly reduce    the size of the    listing
  267. file, as well as making    it quicker to produce.    Do not use this    option
  268. if you will be displaying or listing the list file on a    device which
  269. does not respond to a tab at every 8th position.
  270.  
  271.      The -w keyword specifies the size of the heaps used.  The primary heap
  272. stores the symbol table, user macro text, relocation information, and
  273. cross-reference    information.  The secondary heap stores    information for
  274. nested macro calls and include files.  The primary heap    size defaults to
  275. 32768 bytes, which should be enough for    all but    the largest assemblies.
  276. The secondary heap size    defaults to 1024 bytes,    which should be    enough
  277. unless you use very deeply nested macros and/or    include    files with long
  278. path names.  You can specify either or both parameters.     For example:
  279.     -w40000        secondary heap size remains at 1024 bytes
  280.     -w,2000        primary    heap size remains at 32768 bytes
  281.     -w40000,2000    increases the size of both heaps
  282. If you're really tight for memory, and are assembling small modules, you
  283. can use    this keyword to    shrink the heaps below their default sizes.
  284. At the end of an assembly, a message will be displayed giving the
  285. amount of heap space actually used, in the form    of the -w command
  286. you would have to enter    to allocate the    mininum    heap space.
  287. See below for a    layout of the heaps.
  288.  
  289.      The -x keyword will produce a symbol table    dump, including
  290. cross-reference    information.  If you haven't also specified -l (with
  291. or without a file name), -l with the default file name will be assumed.
  292.  
  293.      The -z keyword is provided    for debugging purposes.     You can cause
  294. the assembler to list a    range of each lines, complete with line    number
  295. and current location counter value, during both    passes.     For example:
  296.     -z        lists all source lines
  297.     -z100,200    lists lines 100    through    200
  298.     -z100        lines all lines    starting at 100
  299.     -z,100        lines the first    100 lines
  300.  
  301.  
  302.      If    you wish to override the default object    and (optionally) listing
  303. file names, you    can omit the -o    and -l keywords.  The assembler    interprets
  304. the first three    parameters without leading hyphens as the source, object,
  305. and listing file names respectively.  Anything over three file names is    an
  306. error, as is attempting    to respecify a file name with the -o or    -l keywords.
  307.  
  308.  
  309.      The primary heap is built from both ends.    Symbol table entries
  310. (including labels) and macro text are stored during pass 1.  Cross-reference
  311. data is    stored during pass 2.  Relocation information is also stored during
  312. pass 2,    but is cleared at the end of each SECTION.  Since it is    no longer
  313. needed once dumped, the    space is freed for re-use by the next section's
  314. relocation information.     The expression    parser also uses the primary heap
  315. to store its working stacks - this space is freed as soon as an    expression
  316. has been evaluated.
  317.      The fixed portion of each symbol table entry occupies 16 bytes.  The
  318. labels and macro text occupy just enough space to hold their strings
  319. (including the end-of-string delimiter)    - they are all pointed to by fixed
  320. symbol table entries.  Relocation entries occupy 10 bytes each.
  321. Cross-reference    entries    are 12 bytes long - each holds four references to
  322. one symbol.  The expression parser creates temporary entries for terms
  323. (10 bytes each)    and operators (4 bytes each).  Since terms are combined
  324. as soon    as possible, the parser    almost never needs to store the    entire
  325. expression on the heap.
  326.      The diagram below illustrates the layout of the primary heap.  High
  327. memory addresses are at    the top    of the diagram,    while low addresses are
  328. at the bottom.    The names on the left of the diagram are the names of the
  329. pointers to the    various    tables within the heap.
  330.  
  331.     Heap + maxheap ------------->  ___________________________
  332.                       |                  |
  333.                       |      Symbol table          |
  334.     struct SymTab *SymStart     ---> |___________________________|
  335.                       |                  |
  336.                       |      Symbol references      |
  337.     struct Ref *RefStart -------> |___________________________|
  338.                       |                  |
  339.                       |      (unused space)      |
  340.     char *HeapLim --------------> |___________________________|
  341.                       |                  |
  342.                       |      Relocation data      |
  343.     struct RelTab *RelStart    ----> |___________________________|
  344.                       |                  |
  345.                       |      Labels and macro text      |
  346.     char *Heap -----------------> |___________________________|
  347.  
  348.      Note that the pointers are    to various types.  This    makes for
  349. lots of    interesting casts.  (Ain't C fun?)  Since the relocation
  350. data is    cleared    at the end of each section, HeapLim will move up and
  351. down.  The "high-water mark" is stored in char *HighHeap, which is
  352. used solely to produce the memory usage    message    at the end of the
  353. assembly.  Note    that a program may consist of a    section    containing
  354. many relocatable references, followed by a section with    fewer
  355. relocatable references but lots    of symbol references.  In this case,
  356. RefStart might end up below HighHeap, and the final message would
  357. indicate that more heap    space was used than was    available.  This is
  358. not an error - only if RefStart    hits HeapLim will an error be reported.
  359.  
  360.  
  361.      The secondary heap    is also    built from both    ends, but it grows and
  362. shrinks    according to how many macros and include files are currently open.
  363. At all times there will    be at least one    entry on the heap, for the original
  364. source code file.
  365.      The bottom    of the heap holds the names of the source code file and
  366. any macro or include files that    are currently open.  The full path is
  367. given.    A null string is stored    for user macros.  Macro    arguments are
  368. stored by additional strings, one for each argument in the macro call line.
  369. All strings are    stored in minimum space, similar to the    labels and user
  370. macro text on the primary heap.     File names are    pointed    to by the fixed
  371. table entries (see below) - macro arguments are    accessed by stepping past
  372. the macro name to the desired argument,    unless NARG would be exceeded.
  373.      The fixed portion of the heap is built down from the top.    Each entry
  374. occupies 16 bytes.  Enough information is stored to return to the proper
  375. position in the    outer file once    the current macro or include file has been
  376. completely processed.
  377.      The diagram below illustrates the layout of the secondary heap.
  378.  
  379.     Heap2 +    maxheap2 ----------->  ___________________________
  380.                       |                  |
  381.                       |      Input    file table      |
  382.     struct InFCtl *InF ---------> |___________________________|
  383.                       |                  |
  384.                       |      Parser operator stack      |
  385.     struct OpStack *Ops --------> |___________________________|
  386.                       |                  |
  387.                       |      (unused space)      |
  388.     struct TermStack *Term -----> |___________________________|
  389.                       |                  |
  390.                       |      Parser term stack      |
  391.     char *NextFNS --------------> |___________________________|
  392.                       |                  |
  393.                       |      Input    file name stack      |
  394.     char *Heap2 ----------------> |___________________________|
  395.  
  396.      The "high-water mark" for NextFNS is stored in char *High2,
  397. and the    "low-water mark" (to stretch a metaphor) for InF is stored
  398. in struct InFCtl *LowInF.  Again, these    figures    are used only to
  399. determine the maximum heap usage.
  400.  
  401.  
  402.      Please send me any    bug reports, flames, etc.  I can be reached on
  403. Dorean BBS (604/432-8579), Mind    Link (604/533-2312), at    any Panorama
  404. (PAcific NORthwest AMiga Association) meeting, or via Jeff Lydiatt
  405. or Larry Phillips.  (I don't have the time or money to live on
  406. Usenet or CompuServe, etc.)
  407.  
  408.                 Charlie    Gibbs
  409.                 #21 - 21555 Dewdney Trunk Road
  410.                 Maple Ridge, B.C.  CANADA
  411.                 V2X 3G6
  412.  
  413.  
  414. P.S.  I    plan to    add 68010/68020    support    in the future.    Stay tuned.
  415.